#ifndef prs_FrmRow_H
#define prs_FrmRow_H

#include "prs_FrmFunc.h"
#include "prs_FrmRules.h"
#include "prs_FrmGeom.h"
#include "prs_FrmControl.h"
#include "prs_FrmRowStyle.h"
#include "prs_FrmUseTemplate.h"
#include "frm_control_TRow.h"

namespace prs {

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmRowCaption : public TNodeFrmControl
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_RowCaption> NodeType;
  TAttrPointerNoCopy<attrName_Control,frm::control::TRowCaption*> Control;
  //
  TNodeFrmRowCaption() : NodeType(this),Control(this),controlEvents(this) {}
  //
  virtual EControlType GetEControlType() { return EControlType_RowCaption;}
  //
  void SetEvents() {
    Control.GetValue()->SetPanelEvents(controlEvents);
  }
  
private:
  TNodeFrmControlEvents controlEvents;  
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmRowChildren : public TNodeFrmControl
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_RowChildren> NodeType;
  TAttrPointerNoCopy<attrName_Control,frm::control::TRowChildren*> Control;
  //
  TNodeFrmRowChildren() : NodeType(this),Control(this) {}
  //
  //void operator = (const TNodeFrmRowChildren &From) { CopyAttrFrom(&From);}
  //
  int GetChildrenCount();
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
struct TNodeFrmRow;
///////////////////////////////////////////////////////////////////////////////

struct TMessage_BeforeVisibleFrmRowChildren : public TMessage_Base
{
  TNodeFrmRow *Sender;
  bool         Visible;
  //
  TMessage_BeforeVisibleFrmRowChildren() {
    Sender = NULL;
  }
};

///////////////////////////////////////////////////////////////////////////////

struct TMessage_AfterVisibleFrmRowChildren : public TMessage_Base
{
  TNodeFrmRow *Sender;
  bool         Visible;
  //
  TMessage_AfterVisibleFrmRowChildren() {
    Sender = NULL;
  }
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmRowControl : public frm::control::TRow
{
  TNodeFrmRowControl(
    frm::control::TWindow &Window,
    TNodeFrmRow &Node
  ):TRow(Window),node(Node) {}
  //
  virtual void UpdateExpand(bool V);
  
private:  
  TNodeFrmRow &node;
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmRow : public TNodeFrmControl
{
  DECLARE_ClientNode()
  //
  typedef TNodeFrmRowStyle   TStyle;
  typedef TNodeFrmRowControl TControl;
  //
  TAttrNodeType<nodeType_Row> NodeType;
  TAttrPointerNoCopy<attrName_Control,TNodeFrmRowControl*> Control;
  TAttrNodeObject<attrName_Caption ,TNodeFrmRowCaption> Caption;
  TAttrNodeObject<attrName_Children,TNodeFrmRowChildren> Children;
  //
  TNodeFrmRow() : NodeType(this),Control(this),Caption(this),Children(this) {}
 ~TNodeFrmRow() { delete Control.GetValue();}
  //
  TNodeFrmRowControl *BuildControl(
    //frm::control::TPanel *ParentControl
    frm::control::TWindow &Window
  );
};

///////////////////////////////////////////////////////////////////////////////

struct TRuleFrmRow : public snt::TRule
{
  TRuleFrmRow(
    snt::text::TContext &Context,
    svl::TVariant &VParentNode,
    TRuleFrmChildrenBase &RChildren,
    TRuleSetNodeIdOptionally &RSetNodeIdOptionally,
    TRuleFrmGeom &RFrmGeom,
    TRuleSetStyle &RStyle
  );

private:  
  TNodeFrmRow *GetNodeRow() { return dynamic_cast<TNodeFrmRow*>(vParentNode.Pointer());}
  void FSetGeometryRow(snt::TParams &Params) { rGeometry.SetGeom( &GetNodeRow()->Geometry.Value );}
  //
  TNodeFrmRowCaption *GetNodeCaption() { return dynamic_cast<TNodeFrmRowCaption*>(vParentNode.Pointer());}
  void FSetCaption (snt::TParams &Params) { vParentNode = &GetNodeRow()->Caption.Value;}
  void FSetGeometryCaption(snt::TParams &Params) { rGeometry.SetGeom( &GetNodeCaption()->Geometry.Value );}
  //
  void FSetChildren(snt::TParams &Params) { vParentNode = &GetNodeRow()->Children.Value;}
  //
  svl::TVariant &vParentNode;
  TRuleFrmGeom &rGeometry;
  snt::TRule  RAttr,RAttr1,RCaption,RCaptionAttr,RCaptionAttr1;
  snt::TAlter AAttr1,ACaptionAttr1;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmRowExpand : public TNodeFrmControl
{
  DECLARE_ClientNode()
  //
  typedef TNodeFrmRowExpandStyle   TStyle;
  typedef frm::control::TRowExpand TControl;
  //
  TAttrNodeType<nodeType_RowExpand> NodeType;
  TAttrPointerNoCopy<attrName_Control,frm::control::TRowExpand*> Control;
  //
  TNodeFrmRowExpand() : NodeType(this),Control(this) {}
 ~TNodeFrmRowExpand() { delete Control.GetValue();}
  //
  void SetStyle(TNodeStyle *NodeStyle);
};

///////////////////////////////////////////////////////////////////////////////

struct TRuleFrmRowExpand : public snt::TRule
{
  TRuleFrmRowExpand(
    snt::text::TContext &Context,
    svl::TVariant &VParentNode,
    TRuleFrmChildrenBase &RChildren,
    TRuleSetNodeIdOptionally &RSetNodeIdOptionally,
    TRuleFrmGeom &RFrmGeom,
    TRuleSetStyle &RStyle
  );

private:  
  TNodeFrmRowExpand *GetNode() { return dynamic_cast<TNodeFrmRowExpand*>(vParentNode.Pointer());}
  void FSetGeometry(snt::TParams &Params) { rGeometry.SetGeom( &GetNode()->Geometry.Value );}
  //
  bool FCheckParentRowCaption(snt::text::TKeyword::TFuncClosureDoEntryParams &Params);
  //
  svl::TVariant &vParentNode;
  TRuleFrmGeom &rGeometry;
  snt::TRule  RAttr,RAttr1;
  snt::TAlter AAttr1;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
